﻿using System.Data.Entity.Validation;
using Wabo.Dal.Interface;
using Wabo.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using EntityFramework.Extensions;

namespace Wabo.Dal.Repository
{
    public class WaboEFUserRepository:EFBaseRepository,IUserRepository
    {
        public User Get(long userId)
        {
            try
            {
                return Context.Users.FirstOrDefault(u => u.id == userId);
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                return null;
            }
        }

        public User Get(string userName,string domain="")
        {
            try
            {
                return Context.Users.FirstOrDefault(u => u.username == userName && (u.domain == domain || String.IsNullOrEmpty(u.domain)));
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                return null;
            }
        }

        public void Remove(User usr)
        {
            try
            {
                Context.Logs.Delete(g => g.user_id == usr.id );
                Context.UserGroups.Delete(g => g.user_id == usr.id);
                Context.Users.Remove(usr);
                Context.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
                Logger.Error(ex.Message);
                throw;
            }
        }

        public void Remove(long userId)
        {
            try
            {
                Context.Users.Remove(Get(userId));
                Context.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
                Logger.Error(ex.Message);
                throw;
            }
        }

        public void Remove(string userName)
        {
            try
            {
                Context.Users.Remove(Get(userName));
                Context.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
                Logger.Error(ex.Message);
                throw;
            }
        }

        public void Update(User usr)
        {
            try
            {
                User original = Get(usr.id);
                if (original != null)
                {
                    Context.Entry(original).CurrentValues.SetValues(usr);
                    Context.SaveChanges();
                }
            }
            catch (DbEntityValidationException ex)
            {
                Logger.Error(ex.Message);
                throw;
            }
        }

        public void Add(ref User usr)
        {
            try
            {                
                Context.Users.Add(usr);
                Context.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
                Logger.Error(ex.Message);
                throw;
            }
        }

        public IEnumerable<User> Users
        {
            get { return Context.Users; }
        }


        public bool Validate(string username, string password,string domain = "")
        {
            try
            {
                User usr = Get(username,domain);
                if (usr != null)
                {
                    if (!usr.locked)
                    {
                        if (!String.IsNullOrEmpty(usr.domain))
                        {
                            ActiveDirectoryHelper.SetDomain(usr.domain);
                            return ActiveDirectoryHelper.IsAuthenticated(username, password);
                        }                    
                        else
                        {
                            return Crypto.ValidateSha1(Crypto.GetSaltedWord(usr.salt, password), usr.password);    
                        }
                        
                    }
                }
                return false;
            }
            catch (DbEntityValidationException ex)
            {
                Logger.Error(ex.Message);
                throw;
            }
        }


        public string CreateHashedPassword(string salt, string password)
        {
            return Crypto.Sha1(Crypto.GetSaltedWord(salt, password));
        }


        public User CreateNewUserObject(string username, string salt, string password, string email)
        {
            return new User
                {
                    username = username,
                    salt = salt,
                    password = CreateHashedPassword(salt, password),
                    email = email
                };            
        }


        public void RemoveAll()
        {
            try
            {
                Context.Logs.Delete(g => true);
                Context.Users.Delete(u => true);
                Context.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
                Logger.Error(ex.Message);
                throw;
            }
        }
    }
}
